x = 10 # 全域變數
def my_func():
x = 5 # 區域變數
print("函式內 x =", x)
my_func()
print("函式外 x =", x)
輸出:
函式內 x = 5
函式外 x = 10
區域變數會覆蓋同名的全域變數,但不會改變外部的值。
count = 0 # 全域變數
def increment():
global count
count += 1
print("函式內 count =", count)
increment()
print("函式外 count =", count)
輸出:
函式內 count = 1
函式外 count = 1
使用 global 關鍵字可以讓函式內部修改全域變數的值。
def outer():
num = 10
def inner():
nonlocal num
num += 5
print("inner num =", num)
inner()
print("outer num =", num)
outer()
輸出:
inner num = 15
outer num = 15
nonlocal 用於內層函式修改外層函式的變數(非全域)。
Python 在函式內偵測到有同名變數賦值,就會視為區域變數,即使你想讀取全域的值也會報錯。
解決方法:
在讀取前加上 global x或更改變數名稱避免衝突
作用域(Scope) 是「哪裡可以存取這個變數」
生命週期(Lifetime) 是「這個變數存在多久」
def my_func():
x = 10 # 區域變數
print(x)
my_func()
print(x) # 會出錯,因為 x 已經不存在
x 的生命週期:
區域變數(Local Variable)
全域變數(Global Variable)
今天的主題讓我更理解變數的「生命週期」與「存取範圍」。
我覺得「生命週期」是一個很有趣的說法:一個變數從建立到消失的整個過程,也就是它在記憶體中存在的時間長短,讓死板板的程式看起來更有生命力了!
關於生命週期,也有一個很形象的比喻——區域變數就像是餐廳臨時借你的桌子,只在你用餐期間存在;全域變數則像是餐廳的收銀台,從開店到打烊都在那裡。
以前在 Java 時,我對作用域的印象比較單純,因為變數幾乎都在方法或類別內定義,很少會混淆。但 Python 有時候容易讓我誤以為在修改全域變數,實際上卻只是建立了一個新的區域變數。
global 和 nonlocal 雖然能解決作用域問題,但使用過多會讓程式變得不易維護,所以在能用傳參數或回傳值解決的情況下,還是要盡量避免直接改全域變數。
明天我要學習模組(import) 與 math / random,開始嘗試使用 Python 內建工具庫,讓程式功能更強大、更方便!